///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _CFONTINFO_H_
#define _CFONTINFO_H_

#include <buola/image.h>
#include <unordered_map>

namespace buola { namespace img {

class CFontInfo
{
public:
    enum EValid
    {
        VALID_NONE=0,
        VALID_FAMILY=(1<<0),
        VALID_STYLE=(1<<1),
        VALID_SLANT=(1<<2),
        VALID_WEIGHT=(1<<3),
        VALID_SIZE=(1<<4),
        VALID_WIDTH=(1<<5),
        VALID_ASPECT=(1<<6),
        VALID_PIXELSIZE=(1<<7),
        VALID_SPACING=(1<<8),
        VALID_FOUNDRY=(1<<9),
        VALID_ANTIALIAS=(1<<10),
        VALID_DPI=(1<<11),
        VALID_ANGLE=(1<<12),

        VALID_HASH=(1<<20)
    };
    DECLARE_FRIEND_ENUM_BITOPS(EValid)

public:
    CFontInfo();
    CFontInfo(const CFontInfo&);
    CFontInfo(const std::string &pFamily,double pSize);
    CFontInfo(const std::string &pFamily,double pSize,const std::string &pStyle);
    CFontInfo(const std::string &pFamily,double pSize,EFontWeight pWeight,EFontSlant pSlant);
    CFontInfo(xml::CNode pNode);
    ~CFontInfo();

    void SetFamily(const std::string &pFamily);
    void SetStyle(const std::string &pStyle);
    void SetSlant(EFontSlant pSlant);
    void SetWeight(EFontWeight pWeight);
    void SetSize(double pSize);
    void SetWidth(int pWidth);
    void SetAspect(double pAspect);
    void SetPixelSize(double pPixelSize);
    void SetSpacing(int pSpacing);
    void SetFoundry(const std::string &pFoundry);
    void SetAntialias(bool pAntialias);
    void SetDPI(double pDPI);
    void SetAngle(double pAngle);

    EValid GetValid() const             {   return mValid;              }
    const std::string &GetFamily() const    {   return mFamily;             }
    const std::string &GetStyle() const     {   return mStyle;              }
    EFontSlant GetSlant() const                {   return mSlant;              }
    EFontWeight GetWeight() const               {   return mWeight;             }
    double GetSize() const              {   return mSize;               }
    int GetWidth() const                {   return mWidth;              }
    double GetAspect() const            {   return mAspect;             }
    double GetPixelSize() const         {   return mPixelSize;          }
    int GetSpacing() const              {   return mSpacing;            }
    const std::string &GetFoundry() const   {   return mFoundry;            }
    bool GetAntialias() const           {   return mAntialias;          }
    double GetDPI() const               {   return mDPI;                }
    double GetAngle() const             {   return mAngle;              }

    bool operator==(const CFontInfo &pOther) const;
    bool operator!=(const CFontInfo &pOther) const;
    CFontInfo& operator=(const CFontInfo &pOther);

    std::size_t GetHash() const;

private:
    void CreateHash() const;

    mutable EValid mValid;

    std::string mFamily;
    std::string mStyle;
    EFontSlant mSlant;
    EFontWeight mWeight;
    double mSize;
    int mWidth;
    double mAspect;
    double mPixelSize;
    int mSpacing;
    std::string mFoundry;
    bool mAntialias;
    double mDPI;
    double mAngle;

    mutable std::size_t mHash;
};

inline io::CTextWriter &operator<<(io::CTextWriter &pWriter,const CFontInfo &pInfo)
{
    pWriter << pInfo.GetHash();
    return pWriter;
}

/*namespace img*/ } /*namespace buola*/ }

namespace std {
    template<>
    struct hash<buola::img::CFontInfo> : public std::unary_function<buola::img::CFontInfo,std::size_t>
    {
        std::size_t operator()(const buola::img::CFontInfo &pInfo) const
        {
            return pInfo.GetHash();
        }
    };
}

#endif
